package com.easyctba.core.algorithm.exec;

import com.easyctba.core.algorithm.domain.EnglishEntropyResp;
import org.springframework.util.StopWatch;

import java.util.HashMap;
import java.util.Set;

/**
 * 英文文本信息熵计算
 */
public class EnglishEntropy {
    public EnglishEntropyResp analyze(String analyticalText){
        var stopWatch = new StopWatch();
        stopWatch.start();
        HashMap<Character, Long> map = new HashMap<>();
        //初始化文本总字符数
        Long sum = 0L;
        char[] chars = analyticalText.toCharArray();
        for (char aChar : chars) {
            //判断数组中的字符是不是大写或者小写字母或者空格
            if ((aChar >= 'a' && aChar <= 'z') || (aChar >= 'A' && aChar <= 'Z') || (aChar == ' ')) {
                sum++;
                if (aChar >= 'A' && aChar <= 'Z') {
                    aChar = (char) (aChar + 32);
                }
                if (!map.containsKey(aChar)) {
                    map.put(aChar, 1L);
                } else {
                    Long aLong = map.get(aChar);
                    aLong++;
                    map.put(aChar, aLong);
                }
            }
        }
        Set<Character> characters = map.keySet();
        double hi = 0;
        for (Character character : characters) {
            //计算概率p
            double p = (double) map.get(character) / (double) sum;
            // 换底公式 ：logx(y)= loge(y)/loge(x)
            //计算信息量Hi
            hi = (Math.log(p) / Math.log(2)) * (-p) + hi;
        }
        stopWatch.stop();
        Long totalTimeNanos = stopWatch.getTotalTimeMillis();
        return new EnglishEntropyResp(hi,sum,totalTimeNanos);
    }
}
